﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Faker {
    public static class AddressFaker {
        public static string ZipCode() {
            var formats = new[] { "#####", "#####-####"};
            return Faker.Letterify(formats.Random());
        }

        public static string UsState() {
            var states = new[] {"Alabama", "Alaska", "Arizona", "Arkansas", "California", "Colorado", "Connecticut", "Delaware", "Florida", "Georgia", "Hawaii", "Idaho", "Illinois", "Indiana", "Iowa", "Kansas", "Kentucky", "Louisiana", "Maine", "Maryland", "Massachusetts", "Michigan", "Minnesota", "Mississippi", "Missouri", "Montana", "Nebraska", "Nevada", "New Hampshire", "New Jersey", "New Mexico", "New York", "North Carolina", "North Dakota", "Ohio", "Oklahoma", "Oregon", "Pennsylvania", "Rhode Island", "South Carolina", "South Dakota", "Tennessee", "Texas", "Utah", "Vermont", "Virginia", "Washington", "West Virginia", "Wisconsin", "Wyoming"};
            return states.Random();
        }

        public static string UsStateAbbr() {
            var states = new[] {
                                   "AL", "AK", "AS", "AZ", "AR", "CA", "CO", "CT", "DE", "DC", "FM", "FL", "GA", "GU",
                                   "HI", "ID", "IL", "IN", "IA", "KS", "KY", "LA", "ME", "MH", "MD", "MA", "MI", "MN",
                                   "MS", "MO", "MT", "NE", "NV", "NH", "NJ", "NM", "NY", "NC", "ND", "MP", "OH", "OK", 
                                   "OR", "PW", "PA", "PR", "RI", "SC", "SD", "TN", "TX", "UT", "VT", "VI", "VA", "WA",
                                   "WV", "WI", "WY", "AE", "AA", "AP" };
            return states.Random();
        }

        private static string CityPrefix() {
            var prefixes = new[] {"North", "East", "West", "South", "New", "Lake", "Port"};
            return prefixes.Random();
        }

        private static string CitySuffix() {
            var suffixes = new[] { "town", "ton", "land", "ville", "berg", "burgh", "borough", "bury", "view", "port", "mouth", 
                                   "stad", "furt", "chester", "mouth", "fort", "haven", "side", "shire" };
            return suffixes.Random();
        }

        public static string City() {
            var cities = new[] {
                string.Format("{0} {1}{2}", CityPrefix(), NameFaker.FirstName(), CitySuffix()),
                string.Format("{0} {1}", CityPrefix(), NameFaker.FirstName()),
                string.Format("{0}{1}", NameFaker.FirstName(), CitySuffix()),
                string.Format("{0}{1}", NameFaker.LastName(), CitySuffix())
            };
            return cities.Random();
        }

        public static string StreetSuffix() {
            var suffixes = new[] {
                                     "Alley", "Avenue", "Branch", "Bridge", "Brook", "Brooks", "Burg", "Burgs", "Bypass"
                                     ,
                                     "Camp", "Canyon", "Cape", "Causeway", "Center", "Centers", "Circle", "Circles",
                                     "Cliff", "Cliffs", "Club", "Common", "Corner", "Corners", "Course", "Court",
                                     "Courts",
                                     "Cove", "Coves", "Creek", "Crescent", "Crest", "Crossing", "Crossroad", "Curve",
                                     "Dale",
                                     "Dam", "Divide", "Drive", "Drives", "Estate", "Estates", "Expressway", "Extension",
                                     "Extensions",
                                     "Fall", "Falls", "Ferry", "Field", "Fields", "Flat", "Flats", "Ford", "Fords",
                                     "Forest", "Forge",
                                     "Forges", "Fork", "Forks", "Fort", "Freeway", "Garden", "Gardens", "Gateway",
                                     "Glen", "Glens",
                                     "Green", "Greens", "Grove", "Groves", "Harbor", "Harbors", "Haven", "Heights",
                                     "Highway", "Hill",
                                     "Hills", "Hollow", "Inlet", "Inlet", "Island", "Island", "Islands", "Islands",
                                     "Isle", "Junction",
                                     "Junctions", "Key", "Keys", "Knoll", "Knolls", "Lake", "Lakes", "Land", "Landing",
                                     "Lane", "Light",
                                     "Lights", "Loaf", "Lock", "Locks", "Locks", "Lodge", "Loop", "Mall", "Manor",
                                     "Manors", "Meadow",
                                     "Meadows", "Mews", "Mill", "Mills", "Mission", "Motorway", "Mount", "Mountain",
                                     "Mountains", "Neck",
                                     "Orchard", "Oval", "Overpass", "Park", "Parks", "Parkway", "Parkways", "Pass",
                                     "Passage", "Path",
                                     "Pike", "Pine", "Pines", "Place", "Plain", "Plains", "Plaza", "Point", "Points",
                                     "Port", "Ports",
                                     "Prairie", "Radial", "Ramp", "Ranch", "Rapid", "Rapids", "Rest", "Ridge", "Ridges",
                                     "River", "Road",
                                     "Roads", "Route", "Row", "Rue", "Run", "Shoal", "Shoals", "Shore", "Shores",
                                     "Skyway", "Spring",
                                     "Springs", "Spur", "Spurs", "Square", "Squares", "Station", "Stravenue", "Stream",
                                     "Street", "Streets",
                                     "Summit", "Terrace", "Throughway", "Trace", "Track", "Trafficway", "Trail",
                                     "Tunnel", "Turnpike", "Underpass",
                                     "Union", "Valley", "Valleys", "Via", "Viaduct", "View", "Views", "Village",
                                     "Villages", "Ville", "Vista",
                                     "Walk", "Walks", "Wall", "Way", "Ways", "Well", "Wells"
                                 };
            return suffixes.Random();
        }

        public static string StreetName() {
            var streets = new[] {
                string.Format("{0} {1}", NameFaker.LastName(), StreetSuffix()),
                string.Format("{0} {1}", NameFaker.FirstName(), StreetSuffix())
            };
            return streets.Random();
        }

        public static string StreetAddress(bool includeSecondary) {
            var formats = new[] {
                                    Faker.Numerify(string.Format("##### {0}", StreetName())),
                                    Faker.Numerify(string.Format("#### {0}", StreetName())),
                                    Faker.Numerify(string.Format("### {0}", StreetName()))
                                };
            return formats.Random() + (includeSecondary ? " " + SecondaryAddress() : "");
        }

        public static string SecondaryAddress() {
            var formats = new[] {
                                    Faker.Numerify("Apt. ###"),
                                    Faker.Numerify("Suite ###")
                                };
            return formats.Random();
        }
    }
}
